Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add object-fit util #95

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

firstchair
Copy link

After using this utility in various projects I thought it would be handy to have it added here.
The util can imitate the CSS object-fit functionally or it do calculations to draw images on canvas element.


This util mimics the CSS property `object-fit` for all HTML elements;

It exports two reusable methods: `contain` and `cover`. Given the sizes of an parent element and its
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It exports two reusable methods: `contain` and `cover`. Given the sizes of an parent element and its
It exports two reusable methods: `contain` and `cover`. Given the sizes of a parent element and its

This util mimics the CSS property `object-fit` for all HTML elements;

It exports two reusable methods: `contain` and `cover`. Given the sizes of an parent element and its
child element: Contain returns the size to be applied to the element to let it fits its parent and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
child element: Contain returns the size to be applied to the element to let it fits its parent and
child element: Contain returns the size to be applied to the element to let it fit its parent and

Contain:

With the contain method you can use both position absolute and relative on the child element.
Relative can be useful if you want to position elements inside absolute to the parent.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relative can be useful if you want to position elements inside absolute

That sounds a bit strange? :)


const objectFit = contain(parentRef.current.offsetWidth, parentRef.current.offsetHeight, 1, 1);

childRef.current.style.cssText += objectFit.cssText;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this is just an example, it could happen that if the parentRef changes, it appends the new cssText to an existing element.

I was thinking the csstext would be used to assign to the JSX with the style tag, but unfortunately that receives an object, and not a text string.

I wonder if it would be useful to have an example like:

const { x: left, y: top, width, height } = contain(parentRef.current.offsetWidth, parentRef.current.offsetHeight, 1, 1);


<div
  ref={childRef}
  style={{ position: 'relative', outline: '1px solid blue', left, top, width, height }}
/>

Or maybe have a cssObj returned with those 4 renamed style props, so it can be used in a similar way to cssText;

Benefit over JSX is that it sets the individual style props (left, top, etc), instead of working with a "dumb" string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're having two tests, one for cover, one for contain.
Both tests have the exact same input, and the exact same output.
How can you be 100% sure, from this tests, that both versions work correctly? :)

});
});

it('throws an error for non-positive input arguments', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, 0 is positive.
Maybe reword (and also in other places) to "greater than 0" ?

@firstchair firstchair changed the title Feature/object fit util Add object-fit util Mar 21, 2023
childWidth: number,
childHeight: number,
): { x: number; y: number; width: number; height: number; scale: number; cssText: string } => {
if ([parentWidth, parentHeight, childWidth, childHeight].some((value) => value <= 0)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using logical operators will be significantly faster compared to Array.some.

if (parentWidth <= 0 || parentHeight <= 0 || childWidth <= 0 || childHeight <= 0) {
  throw new Error(`All arguments should have a positive value`);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants